# BaseEnemy.gd
class_name BaseEnemy
extends CharacterBody2D

# Stats - Can be overridden by specific enemy types or loaded from EnemyData resource
@export var health: float = 10.0
@export var max_health: float = 10.0
@export var move_speed: float = 50.0
@export var damage: float = 5.0
@export var experience_yield: int = 1
@export var attack_cooldown: float = 1.5

# References
@onready var sprite: Sprite2D = $Sprite2D # Replace with AnimatedSprite2D
@onready var collision_shape: CollisionShape2D = $CollisionShape2D
@onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D # Optional for pathfinding
@onready var attack_timer: Timer = $AttackTimer
@onready var health_bar: ProgressBar = $HealthBar # Optional health bar
@onready var hurtbox: Area2D = $Hurtbox # For receiving damage
@onready var hitbox: Area2D = $Hitbox # For dealing damage on contact/melee

var player_node: Node2D = null
var is_dying: bool = false

# Collision: Body on Layer 3 (enemies)
# Hurtbox: Area on Layer 8 (hurtbox), Mask 4 (player_weapon)
# Hitbox: Area on Layer 7 (hitbox), Mask 2 (player) - For contact damage

func _ready():
	add_to_group("enemies")
	max_health = health # Initialize max_health
	update_health_bar()

	# Find player - can be improved (pass reference on spawn?)
	player_node = get_tree().get_first_node_in_group("player")

	if attack_timer:
		attack_timer.wait_time = attack_cooldown
		attack_timer.one_shot = true # Trigger attack, then wait for cooldown again
		attack_timer.timeout.connect(_perform_attack) # Connect timeout to attack function

	if hitbox:
		hitbox.body_entered.connect(_on_hitbox_body_entered) # Connect hitbox for contact damage

	if hurtbox:
		hurtbox.area_entered.connect(_on_hurtbox_area_entered) # Connect hurtbox for weapon damage

	# Navigation setup (optional)
	if navigation_agent:
		navigation_agent.path_desired_distance = 4.0
		navigation_agent.target_desired_distance = 4.0
		# Call set_target_position every frame or periodically
		# navigation_agent.velocity_computed.connect(self._on_navigation_agent_velocity_computed)


func _physics_process(delta):
	if is_dying or GameManager.is_game_over or not player_node:
		velocity = Vector2.ZERO
		move_and_slide() # Ensure it stops sliding
		return

	var direction = Vector2.ZERO
	if navigation_agent and navigation_agent.is_navigation_finished() == false:
		# --- Navigation Agent Movement ---
		navigation_agent.set_target_position(player_node.global_position)
		var next_path_position = navigation_agent.get_next_path_position()
		direction = global_position.direction_to(next_path_position)
		velocity = direction * move_speed
		move_and_slide()
		# Optional: Rotate sprite towards movement direction
		# look_at(global_position + direction)
	else:
		# --- Simple Direct Movement ---
		direction = global_position.direction_to(player_node.global_position)
		velocity = direction * move_speed
		move_and_slide()
		# Optional: Rotate sprite towards player
		# look_at(player_node.global_position)

	# Check distance for attack readiness
	var distance_to_player = global_position.distance_to(player_node.global_position)
	# Adjust attack range as needed (e.g., based on hitbox size)
	var attack_range = 30.0
	if distance_to_player < attack_range and attack_timer and attack_timer.is_stopped():
		attack_timer.start()


# Optional: For NavigationAgent2D velocity computation
#func _on_navigation_agent_velocity_computed(safe_velocity):
	#velocity = safe_velocity
	#move_and_slide()


func take_damage(amount: float, _source_position: Vector2 = Vector2.ZERO):
	if is_dying: return

	health -= amount
	update_health_bar()
	print("%s took %f damage, health: %f" % [self.name, amount, health])

	# Visual Feedback (flash, knockback)
	# modulate = Color.RED
	# await get_tree().create_timer(0.1).timeout
	# modulate = Color.WHITE

	if health <= 0:
		die()


func update_health_bar():
	if health_bar:
		health_bar.max_value = max_health
		health_bar.value = health
		health_bar.visible = health < max_health # Show only when damaged


func _perform_attack():
	# Default: Contact damage (handled by _on_hitbox_body_entered)
	# Override in specific enemy types for ranged or special attacks
	print("%s trying to attack (contact)" % self.name)
	# For ranged: Instantiate projectile scene, set direction, etc.


func _on_hitbox_body_entered(body):
	# If the hitbox touches the player
	if body is Player and not is_dying:
		print("%s hit Player" % self.name)
		body.take_damage(damage)
		# Add knockback or other effects if desired


func _on_hurtbox_area_entered(area):
	# If the hurtbox is hit by a player weapon area
	if area.has_method("get_damage") and not is_dying: # Check if it's a weapon
		var weapon_damage = area.get_damage()
		var crit_roll = randf()
		if player_node and crit_roll < player_node.crit_chance:
			weapon_damage *= player_node.crit_damage_multiplier
			print("CRITICAL HIT!")
		take_damage(weapon_damage, area.global_position)

		# Handle weapon effects like pierce
		if area.has_method("on_hit_enemy"):
			area.on_hit_enemy(self)


func die():
	if is_dying: return
	is_dying = true
	print("%s Died!" % self.name)

	# Stop movement and collision
	set_physics_process(false)
	collision_shape.disabled = true
	if hurtbox: hurtbox.monitoring = false
	if hitbox: hitbox.monitoring = false
	velocity = Vector2.ZERO

	# Emit signal BEFORE freeing
	SignalBus.emit_signal("enemy_died", global_position, experience_yield, self.name) # Or use EnemyData ID

	# Spawn XP orb
	var orb_scene = load("res://scenes/pickups/ExperienceOrb.tscn") # Ensure path is correct
	if orb_scene:
		var orb = orb_scene.instantiate()
		orb.experience_value = experience_yield
		# Get the container node (e.g., from MainGame or Level scene)
		var orb_container = get_tree().get_first_node_in_group("orb_container")
		if orb_container:
			orb_container.add_child(orb)
			orb.global_position = global_position
		else:
			get_parent().add_child(orb) # Fallback: add to own parent
			orb.global_position = global_position
	else:
		printerr("Could not load ExperienceOrb scene!")


	# Play death animation/effect
	# $AnimationPlayer.play("death")
	# await $AnimationPlayer.animation_finished
	queue_free() # Remove from scene tree